package com.example.plugin;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.util.Log;

import com.example.plugin.compat.ActivityThreadCompat;
import com.example.plugin.compat.CompatibilityInfoCompat;
import com.example.plugin.parser.PluginPackageParser;
import com.example.plugin.reflect.FieldUtils;
import com.example.plugin.reflect.MethodUtils;
import com.example.plugin.utils.FileUtils;

import dalvik.system.DexClassLoader;

public class PluginManager {

	private static HashMap<String, PluginPackageParser> mParsers;
	private static HashMap<String, DexClassLoader> mLoaders;

	static {
		mParsers = new HashMap<String, PluginPackageParser>();
		mLoaders = new HashMap<String, DexClassLoader>();
	}

	public static void installPlugin(Context context, File apkFile) {
		PluginPackageParser parser;
		try {
			parser = new PluginPackageParser(context, apkFile);
			mParsers.put(parser.getPackageName(), parser);

			File dexOutputPath = context.getDir("plugin", 0);
			FileUtils.cleanDir(dexOutputPath);
			
			DexClassLoader dexClassLoader = new DexClassLoader(
					apkFile.getAbsolutePath(), dexOutputPath.getAbsolutePath(), null,
					PluginManager.class.getClassLoader());
			
			mLoaders.put(parser.getPackageName(), dexClassLoader);
			
			Object object = ActivityThreadCompat.currentActivityThread();
			Object loadedApk = MethodUtils.invokeMethod(object, "getPackageInfoNoCheck", parser.getApplicationInfo(0), CompatibilityInfoCompat.DEFAULT_COMPATIBILITY_INFO());
			FieldUtils.writeDeclaredField(loadedApk, "mClassLoader", dexClassLoader);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static DexClassLoader getLoader(String pkg) {
		return mLoaders.get(pkg);
	}
	
	public static ComponentName getLauncherComponent(String pkgName) {
		PluginPackageParser parser = mParsers.get(pkgName);
		return parser.getLauncherComponent();
	}

	public static boolean isPlugin(String packageName) {
		return mParsers.containsKey(packageName);
	}

	public static ActivityInfo getActivityInfo(ComponentName component, int flags) throws Exception {
        PluginPackageParser parser = mParsers.get(component.getPackageName());
        if (parser != null) {
            return parser.getActivityInfo(component, flags);
        }
		return null;
	}
	
	public static ActivityInfo resolveActivityInfo(Intent intent)
			throws RemoteException {
		ComponentName component = intent.getComponent();

		if (component != null) {
			PluginPackageParser parser = mParsers.get(component
					.getPackageName());
			List<ActivityInfo> infos = parser.getActivities();
			for (ActivityInfo info : infos) {
				Log.i("bush", "activity: " + info.name);
				if (info.name.equalsIgnoreCase(component.getClassName())) {
					return info;
				}
			}
		}

		return null;
	}
}
